home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / p4 / p4-1_2a.lha / p4-1.2a / lib / p4_bm.c < prev    next >
C/C++ Source or Header  |  1992-10-19  |  13KB  |  442 lines

  1. #include "p4.h"
  2. #include "p4_sys.h"
  3.  
  4. int bm_start(argc, argv)
  5. int *argc;
  6. char **argv;
  7. {
  8.     int bm_switch_port;
  9.  
  10.     sprintf(whoami, "p0_%d", getpid());
  11.     p4_dprintfl(90,"entering bm_start\n");
  12.  
  13.     trap_sig_errs();        /* Errors can happen any time */
  14.  
  15.     logging_flag = FALSE;
  16.     globmemsize = GLOBMEMSIZE;
  17.     sserver_port = 753;
  18.  
  19.     process_args(argc, argv);
  20.  
  21. #   ifdef SYSV_IPC
  22.     sysv_num_shmids = 0;
  23.     sysv_shmid[0]  = -1;
  24.     sysv_semid0 = init_sysv_semset(0);
  25. #   endif
  26.  
  27.     MD_initmem(globmemsize);
  28.     alloc_global();  /* sets p4_global */
  29.  
  30.     if (*bm_outfile)
  31.     {
  32.     freopen(bm_outfile, "w", stdout);
  33.     freopen(bm_outfile, "w", stderr);
  34.     }
  35.  
  36.     p4_local = alloc_local_bm();
  37.     if (p4_local == NULL)
  38.     p4_error("p4_initenv: alloc_local_bm failed\n", NULL);
  39.  
  40.     MD_initenv();
  41.     bm_switch_port = getswport(p4_global->my_host_name);
  42.     usc_init();
  43.  
  44.     /* big master installing himself */
  45.     install_in_proctable(0, (-1), getpid(), p4_global->my_host_name, 
  46.              0, P4_MACHINE_TYPE, bm_switch_port);
  47.  
  48.     p4_local->my_id = 0;
  49.  
  50.     if (logging_flag)
  51.     ALOG_ENABLE;
  52.     else
  53.     ALOG_DISABLE;
  54.  
  55.     return (0);
  56. }
  57.  
  58. int p4_create_procgroup()
  59. {
  60.  
  61.     p4_dprintfl(90,"entering p4_create_procgroup\n");
  62.     if ((p4_local->procgroup = read_procgroup()) == NULL)
  63.     return (-1);
  64.     p4_startup(p4_local->procgroup);
  65. }
  66.  
  67.  
  68. int p4_startup(pg)
  69. struct p4_procgroup *pg;
  70. {
  71.     int i, nslaves;
  72.     int listener_port, listener_fd;
  73.     struct bm_rm_msg bm_msg;
  74.     struct p4_procgroup_entry *local_pg;
  75.  
  76.     p4_dprintfl(90,"entering p4_startup\n");
  77.  
  78.     if (p4_global == NULL)
  79.     p4_error("p4 not initialized; perhaps p4_initenv not called",0);
  80.  
  81.     procgroup_to_proctable(pg);
  82.     if (pg->num_entries > 1)
  83.     p4_global->local_communication_only = FALSE;
  84.  
  85. #   ifdef CAN_DO_SOCKET_MSGS
  86.     if (!p4_global->local_communication_only)
  87.     {
  88.     net_setup_anon_listener(10, &listener_port, &listener_fd);
  89.     p4_global->listener_port = listener_port;
  90.     p4_global->listener_fd = listener_fd;
  91.     p4_dprintfl(90, "setup listener on port %d fd %d\n",
  92.             listener_port, listener_fd);
  93.     p4_global->proctable[0].port = listener_port;
  94.     SIGNAL_P4(LISTENER_ATTN_SIGNAL, handle_connection_interrupt);
  95.     }
  96. #   endif
  97.  
  98.     setup_conntab();
  99.  
  100.     p4_lock(&p4_global->slave_lock);
  101.     if ((nslaves = create_bm_processes(pg)) < 0)
  102.     return (-1);
  103.  
  104. #   ifdef CAN_DO_SOCKET_MSGS
  105.     if (create_remote_processes(pg) < 0)
  106.     return (-1);
  107. #   endif
  108.  
  109.     /* let local slaves use proc table to identify themselves */
  110.     p4_unlock(&p4_global->slave_lock); 
  111.  
  112.     send_proc_table();  /* to remote masters */
  113.  
  114. #   if defined(IPSC860)  ||  defined(CM5)
  115.     /* send initial info and proctable to local slaves */
  116.     /* must use p4_i_to_n procs because node slave 
  117.        does not know if the msg is forwarded from bm */
  118.     local_pg = &(pg->entries[0]);
  119.     bm_msg.type = p4_i_to_n(INITIAL_INFO);
  120.     bm_msg.numinproctab = p4_i_to_n(p4_global->num_in_proctable);
  121.     bm_msg.numslaves = p4_i_to_n(local_pg->numslaves_in_group);
  122.     bm_msg.debug_level = p4_i_to_n(remote_debug_level);
  123.     bm_msg.memsize = p4_i_to_n(globmemsize);
  124.     bm_msg.logging_flag = p4_i_to_n(logging_flag);
  125.     strcpy(bm_msg.application_id, p4_global->application_id);
  126.     strcpy(bm_msg.version, p4_version());
  127.     strcpy(bm_msg.pgm, local_pg->slave_full_pathname);
  128.     for (i = 1; i <= nslaves; i++)
  129.     {
  130.     p4_dprintfl(90,"sending initinfo to slave %d of %d\n",i,nslaves);
  131. #       if defined(IPSC860)
  132.     csend((long) INITIAL_INFO, &bm_msg, (long) sizeof(struct bm_rm_msg), 
  133.           (long) i, (long) NODE_PID);
  134.     csend((long) INITIAL_INFO, p4_global->proctable, 
  135.           (long) sizeof(p4_global->proctable), (long) i, (long) NODE_PID);
  136. #       endif
  137. #       if defined(CM5)
  138.     CMMD_send_noblock(i, INITIAL_INFO, &bm_msg, sizeof(struct bm_rm_msg));
  139.     CMMD_send_noblock(i, INITIAL_INFO, p4_global->proctable, sizeof(p4_global->proctable));
  140. #       endif
  141.     p4_dprintfl(90,"sent initinfo to slave %d of %d\n",i,nslaves);
  142.     }
  143. #   endif
  144.  
  145.     p4_global->low_cluster_id = 
  146.     p4_local->my_id - p4_global->proctable[p4_local->my_id].slave_idx;
  147.     p4_global->hi_cluster_id = 
  148.     p4_global->low_cluster_id + p4_global->local_slave_count + 1;
  149.  
  150.     /* 
  151.        sync with local slaves thus insuring that they have the proctable before 
  152.        syncing with remotes (this keeps remotes from interrupting the local 
  153.        processes too early; then re-sync with local slaves (thus permitting them
  154.        to interrupt remotes)
  155.     */
  156.  
  157.     p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  158.     /* 
  159.        NEED A SYNC WITH LOCALS THAT DOES A BARRIER WITH PROCS THAT SHARE
  160.        MEMORY AND MP BARRIER WITH OTHER "LOCAL" PROCESSES 
  161.     */
  162.     sync_with_remotes();
  163.     p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  164.  
  165.  
  166.     return (0);
  167. }
  168.  
  169. int create_bm_processes(pg)
  170. struct p4_procgroup *pg;
  171. {
  172.     struct p4_procgroup_entry *local_pg;
  173.     struct listener_data *l;
  174.     int i, nslaves, end_1, end_2;
  175.     int slave_pid, listener_pid;
  176.     int slave_idx, listener_fd;
  177.     int port, switch_port;
  178.     struct bm_rm_msg bm_msg;
  179.  
  180.     p4_dprintfl(90,"entering create_bm_processes\n");
  181.     local_pg = &(pg->entries[0]);
  182.  
  183.     nslaves = local_pg->numslaves_in_group;
  184. #   if !defined(IPSC860)  &&  !defined(CM5)
  185.     if (nslaves > P4_MAX_MSG_QUEUES)
  186.     p4_error("more slaves than msg queues \n", nslaves);
  187. #   endif
  188.  
  189. /* alloc listener local data since this proc will eventually become listener */
  190. #   ifdef CAN_DO_SOCKET_MSGS
  191.     if (!(p4_global->local_communication_only))
  192.     {
  193.     listener_fd = p4_global->listener_fd;
  194.     listener_info = alloc_listener_info();
  195.     l = listener_info;
  196.     get_pipe(&end_1, &end_2);
  197.     }
  198. #   endif
  199.  
  200. #   ifdef TCMP
  201.     tcmp_init(NULL,p4_get_my_cluster_id(),shmem_getclunid());
  202. #   endif
  203.  
  204. #   if defined(IPSC860)  ||  defined(CM5)
  205.     for (i = 1; i <= nslaves; i++)
  206.     {
  207.     p4_dprintfl(90,"doing initial sync with local slave %d\n",i);
  208. #       if defined(IPSC860)
  209.     csend((long) SYNC_MSG, &bm_msg, (long) sizeof(struct bm_rm_msg), 
  210.           (long) i, (long) NODE_PID);
  211.     crecv(INITIAL_INFO, &bm_msg, (long) sizeof(struct bm_rm_msg));
  212. #       endif
  213. #       if defined(CM5)
  214.     CMMD_send_noblock(i, SYNC_MSG, &bm_msg, sizeof(struct bm_rm_msg));
  215.         CMMD_receive(CMMD_ANY_NODE, INITIAL_INFO, (void *) &bm_msg, sizeof(struct bm_rm_msg));
  216. #       endif
  217.     port = p4_n_to_i(bm_msg.port);
  218.     slave_idx = p4_n_to_i(bm_msg.slave_idx);
  219.     slave_pid = p4_n_to_i(bm_msg.slave_pid);
  220.     switch_port = p4_n_to_i(bm_msg.switch_port);
  221.     /* big master installing local slaves */
  222.     install_in_proctable(0, port, slave_pid, bm_msg.host_name, 
  223.                  slave_idx, P4_MACHINE_TYPE, switch_port);
  224.     p4_global->local_slave_count++;
  225.     }
  226. #   else
  227.     for (slave_idx = 1; slave_idx <= nslaves; slave_idx++)
  228.     {
  229.     p4_dprintfl(20, "creating local slave %d of %d\n",slave_idx,nslaves);
  230.     slave_pid = fork_p4();
  231.     if (slave_pid < 0)
  232.         p4_error("create_bm_processes fork", slave_pid);
  233.     else
  234.         if (slave_pid)
  235.         p4_dprintfl(10, "created local slave %d\n", slave_idx);
  236.     if (slave_pid == 0)    /* At this point, we are the slave. */
  237.     {
  238.         sprintf(whoami, "bm_slave_%d_%d", slave_idx, getpid());
  239.  
  240.         p4_free(p4_local);    /* Doesn't work for weird memory model. */
  241.         p4_local = alloc_local_slave();
  242.  
  243. #           ifdef CAN_DO_SOCKET_MSGS
  244.         if (!(p4_global->local_communication_only))
  245.         {
  246.         p4_local->listener_fd = end_1;
  247.         close(end_2);
  248.         close(listener_fd);
  249.         }
  250.         SIGNAL_P4(LISTENER_ATTN_SIGNAL, handle_connection_interrupt);
  251. #           endif
  252.  
  253.         /* hang for a valid proctable */
  254.         p4_lock(&p4_global->slave_lock);
  255.         p4_unlock(&p4_global->slave_lock);
  256.  
  257.         p4_local->my_id = p4_get_my_id_from_proc();
  258.         setup_conntab();
  259.         sprintf(whoami, "p%d_%d", p4_local->my_id, getpid());
  260.         usc_init();
  261.  
  262. #           ifdef TCMP
  263.             tcmp_init(NULL,p4_get_my_cluster_id(),shmem_getclunid());
  264. #           endif
  265.  
  266.         /* 
  267.            sync with master twice: once to make sure all slaves have 
  268.            got proctable, and second after the master has synced with the 
  269.            remote processes 
  270.         */
  271.         p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  272.         p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  273.  
  274.         p4_dprintfl(20, "local slave starting\n");
  275.         ALOG_SETUP(p4_local->my_id,ALOG_TRUNCATE);
  276.         ALOG_LOG(p4_local->my_id,BEGIN_USER,0,"");
  277.         slave();
  278.         ALOG_LOG(p4_local->my_id,END_USER,0,"");
  279.         ALOG_OUTPUT;
  280.         p4_dprintfl(20, "local slave exiting\n");
  281.  
  282.         exit(0);
  283.     }
  284.  
  285.     /* master installing local slaves */
  286.     install_in_proctable(0, p4_global->listener_port, slave_pid,
  287.                  p4_global->my_host_name, 
  288.                  slave_idx, P4_MACHINE_TYPE,
  289.                  p4_global->proctable[0].switch_port);
  290.     p4_global->local_slave_count++;
  291.     }
  292. #   endif
  293.  
  294. #   if defined(CM5)
  295.     for (i=nslaves+1; i < CMMD_partition_size(); i++)
  296.         CMMD_send_noblock(i, DIE, &bm_msg, sizeof(struct bm_rm_msg));
  297. #   endif
  298.  
  299.  
  300.     /* Done creating slaves. Now fork off the listener */
  301.  
  302. #   if !defined(IPSC860)  &&  !defined(CM5)
  303.  
  304. #   ifdef CAN_DO_SOCKET_MSGS
  305.     if (!(p4_global->local_communication_only))
  306.     {
  307.     listener_pid = fork_p4();
  308.     if (listener_pid < 0)
  309.         p4_error("create_bm_processes listener fork", listener_pid);
  310.     if (listener_pid == 0)
  311.     {
  312.         sprintf(whoami, "bm_list_%d", getpid());
  313.         /* Inside listener */
  314.         p4_local = alloc_local_listener();
  315.         l->listening_fd = listener_fd;
  316.         l->slave_fd = end_2;
  317.         close(end_1);
  318.         listener();
  319.         exit(0);
  320.     }
  321.     }
  322. #   endif
  323.  
  324.     /* Else we're still in the big master */
  325.     sprintf(whoami, "p0_%d", getpid());
  326.  
  327.     /* We need to close the fds from the listener setup */
  328. #   ifdef CAN_DO_SOCKET_MSGS
  329.     if (!(p4_global->local_communication_only))
  330.     {
  331.     p4_local->listener_fd = end_1;
  332.     close(listener_fd);
  333.     close(end_2);
  334.     p4_global->listener_pid = listener_pid;
  335.     }
  336. #   endif
  337.  
  338. #   endif
  339.  
  340.     dump_global(80);
  341.     p4_dprintfl(90, "create_bm_processes: exiting\n");
  342.     return (nslaves);
  343. }
  344.  
  345.  
  346. P4VOID procgroup_to_proctable(pg)
  347. struct p4_procgroup *pg;
  348. {
  349.     int i, j, ptidx;
  350.     struct p4_procgroup_entry *pe;
  351.  
  352.     if (strcmp(pg->entries[0].host_name,"local") != 0)
  353.     p4_error("local is not first entry in procgroup ",0);
  354.     strcpy(p4_global->proctable[0].host_name,p4_global->my_host_name);
  355.     get_qualified_hostname(p4_global->proctable[0].host_name);
  356.     p4_global->proctable[0].group_id = 0;
  357.     ptidx = 1;
  358.     for (i=0, pe=pg->entries; i < pg->num_entries; i++, pe++)
  359.     {
  360.     for (j=0; j < pe->numslaves_in_group; j++)
  361.     {
  362.         if (i == 0)
  363.         strcpy(p4_global->proctable[ptidx].host_name,p4_global->my_host_name);
  364.         else
  365.         strcpy(p4_global->proctable[ptidx].host_name,pe->host_name);
  366.         get_qualified_hostname(p4_global->proctable[ptidx].host_name);
  367.         p4_global->proctable[ptidx].group_id = i;
  368.         ptidx++;
  369.     }
  370.     p4_global->num_in_proctable = ptidx;
  371.     }
  372. }
  373.  
  374. P4VOID sync_with_remotes()
  375. {
  376.     struct bm_rm_msg msg;
  377.     int i, fd, node, num_rms, rm[P4_MAXPROCS];
  378.  
  379.     p4_dprintfl(90, "sync_with_remotes: starting\n");
  380.  
  381. #   ifdef CAN_DO_SOCKET_MSGS
  382.     p4_get_cluster_masters(&num_rms, rm);
  383.     for (i = 1; i < num_rms; i++)
  384.     {
  385.     node = rm[i];
  386.     fd = p4_local->conntab[node].port;
  387.     net_recv(fd, &msg, sizeof(msg));
  388.     msg.type = p4_n_to_i(msg.type);
  389.     if (msg.type != SYNC_MSG)
  390.         p4_error("sync_with_remotes: bad type rcvd\n",msg.type);
  391.     }
  392.     for (i = 1; i < num_rms; i++)
  393.     {
  394.     node = rm[i];
  395.     fd = p4_local->conntab[node].port;
  396.     msg.type = p4_i_to_n(SYNC_MSG);
  397.     net_send(fd, &msg, sizeof(msg), FALSE);
  398.     }
  399. #   endif
  400. }
  401.  
  402. P4VOID send_proc_table()
  403. {
  404.     int slave_idx, ent;
  405.     int fd;
  406.     struct bm_rm_msg msg;
  407.     struct proc_info *pe;
  408.  
  409.     p4_dprintfl(90, "send_proc_table: starting\n");
  410.  
  411. #   ifdef CAN_DO_SOCKET_MSGS
  412.     for (slave_idx = 1; slave_idx < p4_global->num_in_proctable; slave_idx++)
  413.     {
  414.     if (p4_global->proctable[slave_idx].slave_idx != 0)
  415.         continue;
  416.  
  417.     fd = p4_local->conntab[slave_idx].port;
  418.  
  419.     p4_dprintfl(90, "sending proctable to slave %d on %d:\n", slave_idx, fd);
  420.     if (fd < 0)
  421.         p4_error("send_proc_table: rm entry doesn't have valid fd", fd);
  422.  
  423.     for (ent = 0, pe = p4_global->proctable;
  424.          ent < p4_global->num_in_proctable; ent++, pe++)
  425.     {
  426.         msg.type = p4_i_to_n(PROC_TABLE_ENTRY);
  427.         msg.port = p4_i_to_n(pe->port);
  428.         msg.unix_id = p4_i_to_n(pe->unix_id);
  429.         msg.slave_idx = p4_i_to_n(pe->slave_idx);
  430.         msg.group_id = p4_i_to_n(pe->group_id);
  431.         strcpy(msg.host_name, pe->host_name);
  432.         strcpy(msg.machine_type,pe->machine_type);
  433.         msg.switch_port = p4_i_to_n(pe->switch_port);
  434.         net_send(fd, &msg, sizeof(msg), FALSE);
  435.     }
  436.     p4_dprintfl(90, "  sending end_of_proc_table\n");
  437.     msg.type = p4_i_to_n(PROC_TABLE_END);
  438.     net_send(fd, &msg, sizeof(msg), FALSE);
  439.     }
  440. #   endif
  441. }
  442.